package com.weimob.mcloud.wechatwork.customer.convertor.customer;

import com.weimob.mcloud.wechatwork.core.base.SingleRequest;
import com.weimob.mcloud.wechatwork.core.entity.config.clue.ClueCfg;
import com.weimob.mcloud.wechatwork.core.entity.privatesphere.PrivateSphere;
import com.weimob.mcloud.wechatwork.core.entity.relation.customer.CustomerProcess;
import com.weimob.mcloud.wechatwork.core.entity.relation.customer.CustomerStage;
import com.weimob.mcloud.wechatwork.core.entity.relation.customer.CustomerStageRelation;
import com.weimob.mcloud.wechatwork.core.entity.relation.employee.Department;
import com.weimob.mcloud.wechatwork.core.entity.relation.employee.Employee;
import com.weimob.mcloud.wechatwork.core.enums.clue.PotentialRuleConditionEnum;
import com.weimob.mcloud.wechatwork.core.enums.clue.PotentialRuleTypeEnum;
import com.weimob.mcloud.wechatwork.core.enums.clue.PotentialSettingEnum;
import com.weimob.mcloud.wechatwork.core.enums.customer.CustomerProcessAuthBizTypeEnum;
import com.weimob.mcloud.wechatwork.core.enums.customer.ProcessStatusEnum;
import com.weimob.mcloud.wechatwork.core.service.customer.request.*;
import com.weimob.mcloud.wechatwork.customer.service.user.module.dto.customer.process.dto.CustomerStageDetailDTO;
import com.weimob.mcloud.wechatwork.customer.service.user.module.dto.customer.process.dto.CustomerStageSettingDTO;
import com.weimob.mcloud.wechatwork.customer.service.user.module.dto.customer.process.dto.ProcessAuthDTO;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 *
 * @author jiawei.you01
 * @date 2022/9/13 14:43
 * @since 1.0
 */
@Component
public class CustomerProcessRequestBuilder {

    /**
     * 构建查询单个客户流程请求体
     * @param
     * @param name
     * @return
     */
    public SingleRequest<GetSingleCustomerProcessRequest> buildGetSingleRequest(PrivateSphere privateSphere,String name,String processId){
        GetSingleCustomerProcessRequest getSingleCustomerProcessRequest = new GetSingleCustomerProcessRequest();
        SingleRequest<GetSingleCustomerProcessRequest> singleRequest = new SingleRequest<>();
        getSingleCustomerProcessRequest.setName(name);
        getSingleCustomerProcessRequest.setProcessId(processId);
        getSingleCustomerProcessRequest.setPrivateSphere(privateSphere);
        singleRequest.setData(getSingleCustomerProcessRequest);

        return singleRequest;
    }

    public SingleRequest<UpdateCustomerProcessRequest> buildUpdateRequest(PrivateSphere privateSphere, String processId,
                                                                          String processName,
                                                                          Integer status,
                                                                          List<CustomerStageDetailDTO> customerStage,
                                                                          List<ProcessAuthDTO> processAuthList) {
        CustomerProcess customerProcess = buildCustomProcess(privateSphere, processId,
                processName,status,customerStage,processAuthList);
        UpdateCustomerProcessRequest request = new UpdateCustomerProcessRequest();
        request.setCustomerProcess(customerProcess);

        return new SingleRequest<>(request);
    }

    public SingleRequest<CreateCustomerProcessRequest> buildCreateRequest(PrivateSphere privateSphere, String processName,
                                                                          Integer status,
                                                                          List<CustomerStageDetailDTO> customerStage,
                                                                          List<ProcessAuthDTO> processAuthList) {
        CreateCustomerProcessRequest request = new CreateCustomerProcessRequest();
        CustomerProcess customerProcess = buildCustomProcess(privateSphere,null,processName,status,customerStage,processAuthList);

        request.setCustomerProcess(customerProcess);
        SingleRequest<CreateCustomerProcessRequest> singleRequest = new SingleRequest<>();

        singleRequest.setData(request);
        return singleRequest;
    }


    private CustomerProcess buildCustomProcess(PrivateSphere privateSphere, String processId,
                                               String processName,
                                               Integer status,
                                               List<CustomerStageDetailDTO> customerStage,
                                               List<ProcessAuthDTO> processAuthList){
        CustomerProcess customerProcess = new CustomerProcess();
        customerProcess.setPrivateSphere(privateSphere);
        customerProcess.setPrivateSphereId(privateSphere.getPrivateSphereId());
        customerProcess.setProcessId(processId);
        customerProcess.setProcessName(processName);
        customerProcess.setStatusEnum(ProcessStatusEnum.getEnumByCode(status));
        customerProcess.setCustomerStages(buildCustomerStage(customerStage));
        customerProcess.setCreateTime(new Date());
        customerProcess.setUpdateTime(new Date());
        List<ProcessAuthDTO> employeeAuthList = processAuthList
                .stream()
                .filter(i -> i.getBizType().equals(CustomerProcessAuthBizTypeEnum.EMPLOYEE.getCode()))
                .collect(Collectors.toList());
        List<ProcessAuthDTO> departmentAuthList = processAuthList
                .stream()
                .filter(i -> i.getBizType().equals(CustomerProcessAuthBizTypeEnum.DEPARTMENT.getCode()))
                .collect(Collectors.toList());

        customerProcess.setEmployees(buildEmployee(employeeAuthList));
        customerProcess.setDepartments(buildDepartment(departmentAuthList));

        return customerProcess;
    }

    private List<CustomerStage> buildCustomerStage(List<CustomerStageDetailDTO> customerStageDetailDTOS) {
        if(CollectionUtils.isEmpty(customerStageDetailDTOS)){
            return new ArrayList<>();
        }
        List<CustomerStage> customerStages = new ArrayList<>();
        for (CustomerStageDetailDTO dto : customerStageDetailDTOS) {
            CustomerStage stage = new CustomerStage();
            stage.setStageNo(dto.getStageNo());
            stage.setStageName(dto.getStageName());
            stage.setStageId(dto.getStageId());
            stage.setStageDesc(dto.getStageDesc());
            List<ClueCfg> clueCfgs = new ArrayList<>();
            if(dto.getFollowCfg()!=null) {
                clueCfgs.add(buildClueCfg(dto.getFollowCfg(), PotentialSettingEnum.CUSTOMER_PROCESS_FOLLOW));
            }
            if(dto.getRoundCfg() != null) {
                clueCfgs.add(buildClueCfg(dto.getRoundCfg(), PotentialSettingEnum.CUSTOMER_PROCESS_CYCLE));
            }
            stage.setCfgList(clueCfgs);
            customerStages.add(stage);
        }
        return customerStages;
    }

    private ClueCfg buildClueCfg(CustomerStageSettingDTO settingDTO,PotentialSettingEnum potentialSettingEnum) {
        if(settingDTO == null){
            return null;
        }
        ClueCfg clueCfg = new ClueCfg();
        clueCfg.setId(settingDTO.getId());
        clueCfg.setRuleValue(settingDTO.getRuleValue());
        clueCfg.setRuleOpenFlag(settingDTO.getRuleOpenFlag());
        clueCfg.setDeleted(false);
        clueCfg.setRuleEventValue(8L);
        clueCfg.setRuleConditionEnum(PotentialRuleConditionEnum.GE);
        clueCfg.setPotentialRuleTypeEnum(PotentialRuleTypeEnum.DAY);
        clueCfg.setPotentialSettingEnum(potentialSettingEnum);
        clueCfg.setRuleExtendInfo(settingDTO.getRuleExtendInfo());
        return clueCfg;
    }


    private List<Department> buildDepartment(List<ProcessAuthDTO> departmentAuthList) {
        if(CollectionUtils.isEmpty(departmentAuthList)){
            return new ArrayList<>();
        }
        return departmentAuthList.stream().map(dto -> {
            Department department = new Department();
            department.setId(dto.getBizId());
            return department;
        }).collect(Collectors.toList());

    }

    private List<Employee> buildEmployee(List<ProcessAuthDTO> employeeAuthList) {
        if(CollectionUtils.isEmpty(employeeAuthList)){
            return new ArrayList<>();
        }
        return employeeAuthList.stream().map(dto -> {
            Employee employee = new Employee();
            employee.setId(dto.getBizId());
            return employee;
        }).collect(Collectors.toList());
    }


    public SingleRequest<QueryCustomerProcessRequest> buildQueryList(PrivateSphere privateSphere) {
        QueryCustomerProcessRequest request = new QueryCustomerProcessRequest();
        request.setPrivateSphere(privateSphere);
        return new SingleRequest<>(request);
    }

    public SingleRequest<DeletedCustomerProcessRequest> buildDeletedRequest(PrivateSphere privateSphere, String processId) {
        DeletedCustomerProcessRequest request = new DeletedCustomerProcessRequest();
        request.setPrivateSphere(privateSphere);
        request.setProcessId(processId);
        return new SingleRequest<>(request);
    }

    public SingleRequest<CustomerStageRelation> buildFetchRelationCountRequest(PrivateSphere privateShare, String processId, String stageId) {
        CustomerStageRelation relation = new CustomerStageRelation();
        relation.setPrivateSphere(privateShare);
        relation.setPrivateSphereId(privateShare.getPrivateSphereId());
        CustomerProcess customerProcess = new CustomerProcess();
        customerProcess.setProcessId(processId);
        if(stageId != null){
            CustomerStage stage = new CustomerStage();
            stage.setStageId(stageId);
            relation.setCustomerStage(stage);
        }
        relation.setCustomerProcess(customerProcess);
        return new SingleRequest<>(relation);
    }

    public SingleRequest<UpdateProcessStatusRequest> buildUpdateStatusRequest(PrivateSphere privateSphere, String processId, Integer status) {
        UpdateProcessStatusRequest request = new UpdateProcessStatusRequest();

        request.setPrivateSphere(privateSphere);
        request.setProcessId(processId);
        request.setStatusEnum(ProcessStatusEnum.getEnumByCode(status));
        SingleRequest<UpdateProcessStatusRequest> singleRequest = new SingleRequest<>();
        singleRequest.setData(request);
        return singleRequest;
    }
}
